#include <iostream>
#include <map>
#include <mutex>
#include <shared_mutex>

// 1.unique_lock 基本用法
// std::mutex mtx;
// int shared_data = 0;
// void use_unique() {
//     // lock可自动解锁，也可手动解锁
//     std::unique_lock<std::mutex> lock(mtx);
//     std::cout << "lock success" << std::endl;
//     shared_data++;
//     lock.unlock();
// }
// 判断是否真的占有锁
// void owns_lock() {
//     std::unique_lock<std::mutex> lock(mtx);
//     shared_data++;
//     if (lock.owns_lock()) {
//         std::cout << "owns lock" << std::endl;
//     } else {
//         std::cout << "dosen't owns lock" << std::endl;
//     }
//     lock.unlock();
//     if (lock.owns_lock()) {
//         std::cout << "owns lock" << std::endl;
//     } else {
//         std::cout << "dosen't owns lock" << std::endl;
//     }
// }
// 延迟加锁
// void defer_lock() {
//     std::unique_lock<std::mutex> _lock(mtx, std::defer_lock);
//     if (_lock.owns_lock()) {
//         std::cout << "owns lock" << std::endl;
//     } else {
//         std::cout << "dosen't owns lock" << std::endl;
//     }
//     _lock.lock();
//     if (_lock.owns_lock()) {
//         std::cout << "owns lock" << std::endl;
//     } else {
//         std::cout << "dosen't owns lock" << std::endl;
//     }
// }
// 领养锁
// void adopt_lock() {
//     mtx.lock();
//     std::unique_lock<std::mutex> _lock(mtx, std::adopt_lock);
//     shared_data++;
//     _lock.unlock();
// }
// 转移互斥量所有权
// 互斥量本身不支持move操作，但是unique_lock支持
// std::unique_lock<std::mutex> get_lock() {
//     std::unique_lock<std::mutex> lock(mtx);
//     shared_data++;
//     return lock;
// }
// void use_return() {
//     std::unique_lock<std::mutex> lock(get_lock());
//     shared_data++;
// }

// 2.共享锁
// C++17 - std::shared_mutex与C++14 - std::shared_time_mutex
// class DNService {
//    public:
//     DNService() {}
//
//     void AddDNS(std::string dnsname, std::string dnsentry) {
//         while (_shared_mutex.try_lock()) {
//             _dns_info[dnsname] = dnsentry;
//         }
//         _shared_mutex.unlock();
//     }
//
//     std::string QueryDNS(std::string dnsname) {
//         std::string ret = "";
//         _shared_mutex.lock_shared();
//         auto it = _dns_info.find(dnsname);
//         if (it != _dns_info.end()) {
//             ret = it->second;
//         }
//         _shared_mutex.unlock_shared();
//         return ret;
//     }
//
//    private:
//     std::map<std::string, std::string> _dns_info;
//     mutable std::shared_mutex _shared_mutex;
// };

// 3.递归锁
// class RecursiveDemo {
//    public:
//     RecursiveDemo() {}
//     bool QueryStudent(std::string name) {
//         std::lock_guard<std::recursive_mutex> recursive_lock(_recursive_mtx);
//         auto iter_find = _students_info.find(name);
//         if (iter_find == _students_info.end()) {
//             return false;
//         }
//         return true;
//     }
//     void AddScore(std::string name, int score) {
//         std::lock_guard<std::recursive_mutex> recursive_lock(_recursive_mtx);
//         if (!QueryStudent(name)) {
//             _students_info.insert(std::make_pair(name, score));
//             return;
//         }
//         _students_info[name] = _students_info[name] + score;
//     }
//     // 不推荐采用递归锁，使用递归锁说明设计思路并不理想，需优化设计
//     // 推荐拆分逻辑，将共有逻辑拆分为统一接口
//
//     void AddScoreAtomic(std::string name, int score) {
//         std::lock_guard<std::recursive_mutex> recursive_lock(_recursive_mtx);
//         auto iter_find = _students_info.find(name);
//         if (iter_find == _students_info.end()) {
//             _students_info.insert(std::make_pair(name, score));
//             return;
//         }
//         _students_info[name] = _students_info[name] + score;
//         return;
//     }
//
//    private:
//     std::map<std::string, int> _students_info;
//     std::recursive_mutex _recursive_mtx;
// };

int main() {
    // 1.unique_lock 基本用法
    // use_unique();
    // owns_lock();
    // defer_lock();
    // adopt_lock();
    // use_return();
    return 0;
}